import { endUnitReg, endWithRpxOrUpxReg, strToNumReg } from "@/utils/reg.js"; // 引入正则表达式

import colorInfo from "@/utils/color.js"; // 引入主题色配置

let loadingTimer = null; //加载中定时器
let loadingTimer2 = null; // 加载中定时器
let toastTimer = null; // 弹框定时器


/**
 * @description 获取节点信息
 * @param selector 节点选择器
 * @param self 如果是在组件内，需要传入this
 * @returns {Promise<unknown>}
 */
export function getRect(selector, self) {
	return new Promise((resolve) => {
		if (!self) {
			// console.log("获取页面节点信息");
			const query = uni.createSelectorQuery();
			query
				.select(selector)
				.boundingClientRect(resolve)
				.exec();
		} else {
			// console.log("获取组件节点信息");
			// 获取组件的节点布局信息
			const query = uni.createSelectorQuery().in(self);
			query
				.select(selector)
				.boundingClientRect(resolve)
				.exec();
		}
	});
}



/**
 * @description 去除字符串空格
 * @param str 字符串内容
 * @param pos 去除空格的方式
 * @returns {*}
 */
export function trim(str, pos = "both") {
	if (typeof str !== "string") return str;
	switch (pos) {
		// 去除两边空格
		case "both":
			return str.replace(/^\s+|\s+$/g, "");
		// 去除左边空格
		case "left":
			return str.replace(/^\s*/, "");
		// 去除右边空格
		case "right":
			return str.replace(/(\s*$)/g, "");
		// 去除所有空格
		case "all":
			return str.replace(/\s+/g, "");
		default:
			return str;
	}
}

/**
 * @description 显示loading加载中
 * @param title 标题
 * @param mask 是否开启禁止操作遮罩
 * @param loadingTime 加载时间
 */
export function showLoading(title, mask, loadingTime) {
	// 默认10秒关闭
	loadingTime = Number(loadingTime) >= 0 ? Number(loadingTime) : 10000;
	uni.showLoading({
		title: title || "正在加载中...",
		mask: mask !== false,
	});
	// 每次调用之前清除定时器
	loadingTimer && clearTimeout(loadingTimer);
	// 最长10s自动关闭
	loadingTimer = setTimeout(() => {
		uni.hideLoading();
	}, loadingTime);
}

/**
 * @description 隐藏loading
 * @param loadingTime 多少秒后隐藏loading
 * @param callback 关闭loading后的回调
 */
export function hideLoading(loadingTime, callback) {
	// 默认loading时间是300ms
	loadingTime = Number(loadingTime) >= 0 ? Number(loadingTime) : 300;
	if (loadingTime > 0) {
		// 每次调用之前清除定时器
		loadingTimer2 && clearTimeout(loadingTimer2);
		// 最短loadingTime加载时间
		loadingTimer2 = setTimeout(() => {
			uni.hideLoading();
			typeof callback === "function" && callback();
		}, loadingTime);
	} else {
		// 清除showLoading的定时器
		loadingTimer && clearTimeout(loadingTimer);
		uni.hideLoading();
	}
}

/**
 * @description 检测数据类型
 * @param target 检测的目标
 * @returns {string}
 */
export function checkType(target) {
	return Object.prototype.toString
		.call(target)
		.slice(8, -1)
		.toLowerCase();
}

/**
 * @description 动态添加单位
 * @param val 传过来的参数
 * @param unit 要拼接的单位
 * @returns {string}
 */
export function addUnit(val = "", unit = "rpx") {
	// 0的情况特殊处理下
	if (val === 0 || val === "0" || val === "0px") return "0px";
	// 如果属性不传值或者设置空字符串，会把属性值变成true，这里特殊处理下，返回auto。
	if (!val || val === true) return "auto";
	// 将数据类型转换成字符串类型，并去掉所有空格
	val = String(val).replace(/\s+/g, "");
	// 包含css计算属性的话，返回对应的字符串
	if (val.includes("calc(")) return val;
	// 提取所有数字部分，匹配到的话是个数组，匹配不到是null
	const matchList = val.match(strToNumReg);
	// console.log(matchList);
	// 匹配不到，或者包含auto，全部取auto
	if (!matchList || val.includes("auto")) return "auto";
	// 匹配到了就取数组最后一个
	const matchVal = matchList[matchList.length - 1];
	// 判断字符串是否以rpx、upx结尾，并拼接上rpx
	if (endWithRpxOrUpxReg.test(val)) {
		val = matchVal + "rpx";
	} else if (endUnitReg.test(val)) {
		// 判断字符串中是否以%、vw、vh、rem、em、px结尾，拼接上对应单位
		val = matchVal + val.match(endUnitReg)[0];
	} else {
		// 只有纯数字的情况下就拼接unit
		val = matchVal + unit;
	}
	// console.log(val);
	return val;
}

/**
 * @description 全局showToast
 * @param title 标题
 * @param showIcon 是否显示成功图标
 * @param callback 回调函数
 * @param mask 是否显示遮罩
 * @param duration 显示时长
 */
export function showToast(title, showIcon, callback, mask, duration) {
	duration = Number(duration) >= 0 ? Number(duration) : 1500; // 默认弹框时间1500ms
	uni.showToast({
		title: title || "",
		icon: !showIcon || (title && title.length > 7) ? "none" : "success",
		mask: mask !== false,
		duration: duration,
		complete: () => {
			// 判断callback是否是函数，如果不是函数就不执行
			if (checkType(callback) !== "function") return;
			// 每次调用之前清除定时器
			toastTimer && clearTimeout(toastTimer);
			// 延时回调
			toastTimer = setTimeout(() => {
				callback();
			}, duration);
		},
	});
}

/**
 * @description 全局showModal
 * @param content 模态框内容
 * @param title 模态框标题
 * @param cancelText 取消按钮文字
 * @param confirmText 确定按钮文字
 * @param confirmColor 确定按钮颜色
 * @param cancelColor 取消按钮颜色
 */
export function showModal(
	content,
	title,
	cancelText,
	confirmText,
	confirmColor,
	cancelColor
) {
	content = typeof content === "string" ? content : "";
	title = typeof title === "string" ? title : "温馨提示";
	// 取消文字特殊处理
	if (cancelText === undefined) {
		cancelText = "取消";
	} else if (!cancelText) {
		cancelText = "";
	} else {
		cancelText = typeof cancelText === "string" ? cancelText : "取消";
	}
	confirmText = typeof confirmText === "string" ? confirmText : "确定";
	confirmColor =
		typeof confirmColor === "string" ? confirmColor : colorInfo.themeColor;
	cancelColor =
		typeof cancelColor === "string" ? cancelColor : colorInfo.fontColor;
	return new Promise((resolve) => {
		uni.showModal({
			title: title,
			cancelText: cancelText,
			confirmText: confirmText,
			confirmColor: confirmColor,
			cancelColor: cancelColor,
			showCancel: cancelText.length > 0,
			content: content,
			success: (res) => {
				if (res.confirm) {
					resolve(true);
				} else if (res.cancel) {
					resolve(false);
				}
			},
			fail: (err) => {
				console.log("模态框异常", err);
			},
		});
	});
}

/**
 * @description 预览大图
 * @param {Object} urls 图片地址
 * @param {Object} current 图片索引
 */
export function previewImage(urls, current) {
	current = Number(current) >= 0 ? Number(current) : 0; // 默认当前索引是0，就是第1张
	// 传入的图片是数组就直接赋值
	if (checkType(urls) === "array" && urls.length > 0) {
		uni.previewImage({
			urls,
			current: current,
			fail: (err) => {
				showToast("预览图片失败");
				console.log("数组类型，预览图片失败", err);
			},
		});
	} else if (checkType(urls) === "string" && urls.length > 0) {
		// 传入的是字符串，就单张预览
		uni.previewImage({
			urls: [urls],
			current: current,
			fail: (err) => {
				showToast("预览图片失败");
				console.log("字符串类型，预览图片失败", err);
			},
		});
	} else {
		console.log("预览图片失败，数据格式不正确", urls);
	}
}

/**
 * @description 拨打电话
 * @param phoneNumber 电话号码
 */
export function makePhoneCall(phoneNumber) {
	// if (!phoneNumber) return showToast("拨打电话失败，电话号码不合法");
	// uni.makePhoneCall({
	// 	phoneNumber: phoneNumber + "",
	// 	success: () => {
	// 		console.log("拨打电话成功");
	// 	},
	// 	fail: (err) => {
	// 		if (err.errMsg.includes("cancel")) {
	// 			console.log("取消拨打电话");
	// 		} else {
	// 			showToast("拨打电话失败");
	// 			console.log(err);
	// 		}
	// 	},
	// });
}


/**
 * @description 比较版本号大小
 * @param {string} v1
 * @param {string} v2
 * @returns {number} 1：有新版本 -1:没有新版本 0：版本号一致
 */
export function compareVersion(v1, v2) {
	v1 = v1.split(".");
	v2 = v2.split(".");
	const len = Math.max(v1.length, v2.length);
	while (v1.length < len) {
		v1.push("0");
	}
	while (v2.length < len) {
		v2.push("0");
	}
	for (let i = 0; i < len; i++) {
		const num1 = parseInt(v1[i], 10);
		const num2 = parseInt(v2[i], 10);

		if (num1 > num2) {
			return 1;
		} else if (num1 < num2) {
			return -1;
		}
	}
	return 0;
}